package com.learnjava.learnjava1.jpa.specification;

import com.learnjava.learnjava1.jpa.entity.CompanyEntity_;
import com.learnjava.learnjava1.jpa.entity.DepartmentEntity;
import com.learnjava.learnjava1.jpa.entity.DepartmentEntity_;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.Join;
import org.springframework.data.jpa.domain.Specification;

import java.util.Optional;
import java.util.stream.Stream;

public class DepartmentSpecification {
    public static Specification<DepartmentEntity> parseFilters(String title, Boolean active, Long id, Long companyId) {
        Optional<Specification<DepartmentEntity>> spec = Stream.of(
                hasId(id),
                hasActive(active),
                hasTitle(title),
                hasCompanyId(companyId)
        ).reduce(Specification::allOf);
        return spec.orElse(null);
    }

    private static Specification<DepartmentEntity> hasTitle(String title) {
        return (root, query, criteriaBuilder) -> {
            if (title == null || title.isEmpty()) {
                return null;
            }
            return criteriaBuilder.like(criteriaBuilder.lower(root.get(DepartmentEntity_.TITLE)), "%" + title.toLowerCase() + "%");
        };
    }

    private static Specification<DepartmentEntity> hasActive(Boolean active) {
        return (root, query, criteriaBuilder) -> {
            if (active == null) {
                return null;
            } else {
                return criteriaBuilder.equal(root.get(DepartmentEntity_.IS_ACTIVE), Boolean.parseBoolean(String.valueOf(active)));
            }
        };
    }

    private static Specification<DepartmentEntity> hasId(Long id) {
        return (root, query, criteriaBuilder) -> {
            if (id == null) {
                return null;
            } else {
                return criteriaBuilder.equal(root.get(DepartmentEntity_.ID), id);
            }
        };
    }

    private static Specification<DepartmentEntity> hasCompanyId(Long companyId) {
        return (root, query, criteriaBuilder) -> {
            if (companyId == null) {
                return null;
            } else {
                Join join =root.join("company");
                return criteriaBuilder.equal(join.get("id"),companyId);
            }
        };
    }


}
